﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using JWT;
using JWT.Algorithms;
using JWT.Serializers;
using Newtonsoft.Json;
using System.Web.Http.Controllers;
using System.Text;
using System.Web.Helpers;

namespace WebApplication.Controllers
{
    public class Result
    {
        public bool success { get; set; }
        public string[] errs { get; set; }
    }
    public class MyAuthorizeAttribute:AuthorizeAttribute
    {
        // Todo 加入角色控制
        public override void OnAuthorization(HttpActionContext actionContext)
        {
            var token = actionContext.Request.Headers.Authorization; 
            if (token != null)
            {
                try
                {
                    UserInfo userinfo = JwtHelp.GetJwtDecode(token.ToString());
                    if (userinfo.Expired>DateTime.Now)
                    {
                        IsAuthorized(actionContext);
                    }
                    else
                    {
                        HandleUnauthorizedRequest(actionContext);
                    }
                }
                catch
                {
                    HandleUnauthorizedRequest(actionContext);
                }                         
            }
            else
            {
                base.OnAuthorization(actionContext);
            }
        }


        protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
        {
            base.HandleUnauthorizedRequest(actionContext);
            var response = actionContext.Response = actionContext.Response ?? new HttpResponseMessage();
            response.StatusCode = HttpStatusCode.Forbidden;
            var content = new Result
            {
                success = false,
                errs = new[] { "服务端拒绝访问：你没有权限，或者掉线了" }
            };
            response.Content = new StringContent(Json.Encode(content), Encoding.UTF8, "application/json");
        }
    }

    

    public class UserInfo
    {
        public string UserName { get; set; }
        public DateTime Expired { get; set; }
    }

    public class DataResult
    {
        public string Token { get; set; }
        public bool Success { get; set; }
        public string Message { get; set; }
    }

    public class JwtHelp
    { 
        private static string secret = "oYCfXIHO8eA4BDZWZpo3bzZNmr0F6eEhRvSqw8EiOeAGI5INGlfOkQ6mZYMT1UwaAl0r";

        /// <summary>
        /// 生成JwtToken
        /// </summary>
        /// <param name="payload">不敏感的用户数据</param>
        /// <returns></returns>
        public static string SetJwtEncode(Dictionary<string, object> payload)
        {
            IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
            IJsonSerializer serializer = new JsonNetSerializer();
            IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
            IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);

            var token = encoder.Encode(payload, secret);
            return token;
        }

        /// <summary>
        /// 根据jwtToken  获取实体
        /// </summary>
        /// <param name="token">jwtToken</param>
        /// <returns></returns>
        public static UserInfo GetJwtDecode(string token)
        {
            IJsonSerializer serializer = new JsonNetSerializer();
            IDateTimeProvider provider = new UtcDateTimeProvider();
            IJwtValidator validator = new JwtValidator(serializer, provider);
            IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
            IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);
            var userInfo = decoder.DecodeToObject<UserInfo>(token, secret, verify: true);//token为之前生成的字符串
            return userInfo;
        }
    }
    
    [RoutePrefix("api/jwtfn")]
    public class JwtController : ApiController
    {
        // GET api/Jwt
        [Route("gettoken/{pwd}/{username}")]
        public HttpResponseMessage Get(string username, string pwd)
        {
            DataResult result = new DataResult();
            if (username == "admin" && pwd == "123")
            {
                var payload = new Dictionary<string, object>
                {
                    { "UserName",username },
                    { "Expired", DateTime.Now.AddDays(2) }
                };
                result.Token = JwtHelp.SetJwtEncode(payload);
                result.Success = true;
                result.Message = "成功";
            }
            else
            {
                result.Token = "";
                result.Success = false;
                result.Message = "失败";
            }

            string json = JsonConvert.SerializeObject(result);
            return new HttpResponseMessage { Content = new StringContent(json, System.Text.Encoding.UTF8, "application/json") };
        }
    }
}
